import Setting from "../config/Setting";
import BaseView from "./BaseView";
import * as vscode from "vscode";

export default class EmptyLineView extends BaseView {
    constructor() {
        super();
    }

    private readonly acceptLanguage = [
        "javascript",
        "typescript"
    ];

    private _doc: vscode.TextDocument | undefined;
    private _backUp: string | undefined;

    public init(): boolean {
        this._doc = undefined;
        this._backUp = undefined;
        let _edt = vscode.window.activeTextEditor;
        if (!_edt) {
            vscode.window.showErrorMessage("当前没有文档打开");
            return false;
        }

        let _doc = _edt.document;
        if (!this.acceptLanguage.includes(_doc.languageId)) {
            let _errMsg = "打开文档的语言不合要求。\n被接受的语言类型为:\n";
            _errMsg += this.acceptLanguage.join(", ");
            vscode.window.showErrorMessage(_errMsg);
            return false;
        }

        this._doc = _doc;
        this._backUp = this._doc.getText();
        vscode.window.showInformationMessage(`请保持文档*${this._doc.fileName}*打开状态`);
        return true;
    }

    public show(msg: string[]): void {
        this.insertBookToDoc(msg)
        .then(() => {
            // this.insertBookToDoc(msg);
        })
        .catch((reason: string | null) => {
            if (reason) {
                vscode.window.showErrorMessage(reason);
            }
        });

        
    }

    public hide(): void {
        // throw new Error("Method not implemented.");
        this.resumeToBackUp();
    }

    public getLineNum(): number {
        return Setting.pageLine;
    }
    
    private resumeToBackUp(): Promise<any> {
        return new Promise((resolve: (v?: any)=>void, reject: (reason: string | null)=>void) => {
            if (!this._doc) {
                reject(null);
                return;
            }
            if (this._doc.isClosed) {
                // vscode.window.showErrorMessage();
                reject(`文档*${this._doc.fileName}*已关闭,请重新启动fishReader!`);
                return;
            }
            let _edt = vscode.window.activeTextEditor;
            if (!_edt) {
                // vscode.window.showErrorMessage();
                reject("当前没有文档打开");
                return;
            }
            if (_edt.document.fileName !== this._doc.fileName) {
                // vscode.window.showErrorMessage();
                reject(`当前编辑的文档不是*${this._doc.fileName}*`);
                return;
            }
            
            _edt.edit((editBuilder) => {
                if (!this._doc || !this._backUp) {
                    reject(null);
                    return;
                }
                let _start = new vscode.Position(0, 0);
                let _end = new vscode.Position(this._doc.lineCount + 1, 0);
                editBuilder.replace(new vscode.Range(_start, _end), this._backUp);
                this._doc.save();
                resolve();
            });
        });
    }

    private insertBookToDoc(msg: string[]): Promise<any> {
        return new Promise(async (resolve: (v?:any)=>void, reject) => {
            if (!this._doc || !this._backUp) {
                reject(null);
                return;
            }
            if (this._doc.isClosed) {
                // vscode.window.showErrorMessage();
                reject(`文档*${this._doc.fileName}*已关闭,请重新启动fishReader!`);
                return;
            }
            let _edt = vscode.window.activeTextEditor;
            if (!_edt) {
                // vscode.window.showErrorMessage();
                reject("当前没有文档打开");
                return;
            }
            if (_edt.document.fileName !== this._doc.fileName) {
                // vscode.window.showErrorMessage();
                reject(`当前编辑的文档不是*${this._doc.fileName}*`);
                return;
            }

            const _docArr = this._backUp.split("\n");
    
            let _mindex = 0;
            let _dindex = 0;
    
            while (_mindex < msg.length) {
                if (_dindex >= _docArr.length) {
                    _docArr[_dindex] = this.getIndentStr(_docArr, _dindex) + "//" + msg[_mindex];
                    _dindex++;
                    _mindex++;
                    continue;
                }

                let _docStr = _docArr[_dindex];
                if (!(/\S/gi.test(_docStr))) {
                    _docArr[_dindex] = this.getIndentStr(_docArr, _dindex) + "//" + msg[_mindex];
                    _dindex++;
                    _mindex++;
                    continue;
                }
                _dindex++;
            }

            _edt.edit((editBuilder) => {
                if (!this._doc || !this._backUp) {
                    reject(null);
                    return;
                }
                let _start = new vscode.Position(0, 0);
                let _end = new vscode.Position(this._doc.lineCount + 1, 0);
                editBuilder.replace(new vscode.Range(_start, _end), _docArr.join("\n"));
                // this._doc.save();
                resolve();
            });
        });
        
    }

    public getIndentStr(arr: string[], index: number): string {
        let _i = index;
        let _str = "";
        if (index >= arr.length) {
            return _str;
        }

        let _ostr = arr[_i];
        while (!(/\S/gi.test(_ostr))) {
            _i++;
            if (_i >= arr.length) {
                return _str;
            }
            _ostr = arr[_i];
        }

        for (let i = 0; i < _ostr.length; i++) {
            const _char = _ostr[i];
            if (/\S/gi.test(_char)) {
                break;
            }
            else {
                _str += _char;
            }
        }

        return _str;
    }
}